// 普通函数
fn square(x: i32) -> i32 {
    x * x
}

// 高阶函数，函数作为参数，常与闭包（匿名函数）结合使用
fn cube(f: fn(i32) -> i32, x: i32) -> i32 {
    f(x) * x
}
fn main() {
    // 常规
    let x = 3;
    println!("x = {}", x);

    let x = 3;
    let x = square(x);
    println!("x = {}", x);

    let x = 3;
    let x = cube(square, x);
    println!("x = {}", x);

    // 闭包
    let x = 3;
    let x = cube(|x| x * x, x);
    println!("x = {}", x);

    // 高阶函数与集合
    let v = [1, 2, 3, 4, 5, 6, 7].to_vec();
    println!("v = {:?}", v);
    /*
     * 以下代码，GPT提出1个错误和2个优化点
     * 错误
     *   1. 闭包参数位置加&是错误，应该到square()位置，对参数进行解引用
     * 优化
     *   1. iter()方法参数类型为&i32，into_iter()方法参数类型i32，使用into_iter在square()位置就可以直接对参数进行使用
     *   2. 在map()方法中不必显示的提供参数和方法名，直接传入square()方法更简洁
     */
    // let v: Box<_> = v.iter().map(|&x| square(x)).collect();
    let v: Vec<i32> = v.into_iter().map(square).collect();
    println!("v = {:?}", v);

    // map方法
    let a = [1, 3, 5, 7, 9];
    println!("a = {:?}", a);
    // 这里数组是固定大小的，没有提供消耗所有者的迭代器into_iter()
    let a: Vec<i32> = a.iter().map(|x| x + x).collect();
    println!("a = {:?}", a);

    // filter方法
    let a = [1, 2, 3, 4, 5, 6, 7];
    println!("a = {:?}", a);
    let a = a.iter().filter(|&x| x % 2 == 0).collect::<Vec<_>>();
    println!("a = {:?}", a);

    // fold方法
    let a = [1, 2, 3, 4, 5, 6, 7];
    println!("a = {:?}", a);
    let a = a.iter().fold(0, |acc, &x| acc + x);
    println!("a = {}", a);
}
